"use strict";

module.exports = core;

// require支持加载 .js/.json/.node
// 如果是其他文件类型会先默认使用加载.js的方式来进行解

const path = require("path");
const pkg = require("../package.json");
const log = require("@luo-cli-dev/log");
const constant = require("./constant");
const semver = require("semver");
const colors = require("colors/safe");
const userHome = require("user-home");
const commander = require("commander");
const pathExists = require("path-exists").sync;
const exec = require("@luo-cli-dev/exec");

let args;
const program = new commander.Command();

// 脚手架执行第一步
async function core() {
  try {
    await prepare();
    registerCommand();
  } catch (err) {
    if (program.debug) {
      log.error(err.message);
    }
  }
}

// 注册命令
function registerCommand() {
  // console.log('test',program)
  program
    .name(Object.keys(pkg.bin)[0])
    .usage("<command> [options]")
    .version(pkg.version)
    .option("-d, --debug", "是否开启调试模式", false)
    .option("-tp, --targetPath <targetPath>", "是否指定本地调试文件路径", "");

  program
    .command("init [projectName]")
    .option("-f, --force", "是否强制初始化项目")
    .action(exec);

  // program
  //   .command('publish')
  //   .option('--refreshServer', '强制更新远程Git仓库')
  //   .option('--refreshToken', '强制更新远程仓库token')
  //   .option('--refreshOwner', '强制更新远程仓库类型')
  //   .action(exec);

  // 开启debug模式
  program.on("option:debug", function () {
    if (program._optionValues.debug) {
      process.env.LOG_LEVEL = "verbose";
    } else {
      process.env.LOG_LEVEL = "info";
    }
    log.level = process.env.LOG_LEVEL;
    log.info("debug");
    // console.log(program._optionValues.debug);
  });

  // 指定targetPath
  program.on("option:targetPath", function () {
    // _optionValues: { debug: true, targetPath: '/aa' },
    // process.env.CLI_TARGET_PATH = program.targetPath; // 旧
    process.env.CLI_TARGET_PATH = program._optionValues.targetPath; // 新
  });

  // 对未知命令监听
  program.on("command:*", function (obj) {
    const availableCommands = program.commands.map((cmd) => cmd.name());
    console.log(colors.red("未知的命令：" + obj[0]));
    if (availableCommands.length > 0) {
      console.log(colors.red("可用命令：" + availableCommands.join(",")));
    }
  });

  program.parse(process.argv);

  if (program.args && program.args.length < 1) {
    program.outputHelp();
    console.log();
  }
}

// prepare 阶段
async function prepare() {
  checkPkgVersion();
  checkNodeVersion();
  checkRoot();
  checkUserHome();
  // checkInputArgs();
  // log.verbose("debug", "test cli debug");
  checkEnv();
  await checkGlobalUpdate();
}

// 检查脚手架版本
function checkPkgVersion() {
  console.log(pkg.version);
  log.info("cli", pkg.version);
}

// 检查node版本
function checkNodeVersion() {
  const currentVersion = process.version;
  const lowestVersion = constant.LOWEST_NODE_VERSION;
  // node版本过低
  if (!semver.gte(currentVersion, lowestVersion)) {
    throw new Error(
      colors.red(`luo-cli需要安装node v${lowestVersion}以上版本`)
    );
  }
}

// root账号检查
function checkRoot() {
  const rootCheck = require("root-check");
  rootCheck(); // root账号启动检查并自动降级
  console.log("当前uid", process.geteuid()); // 501  root账号默认是0但降级后还是501保持用sudo启动脚手架里的权限不变
}

// 检查用户主目录是否存在
function checkUserHome() {
  console.log("主目录", userHome);
  // 不存在用户主目录或
  if (!userHome || !pathExists(userHome)) {
    throw new Error(colors.red("当前用户主目录不存在"));
  }
}

// 检查入参 被commander取代
function checkInputArgs() {
  const minimist = require("minimist");
  args = minimist(process.argv.slice(2));
  checkArgs();
}

function checkArgs() {
  // console.log('args', args);
  if (args.debug) {
    process.env.LOG_LEVEL = "verbose";
  } else {
    process.env.LOG_LEVEL = "info";
  }
  log.level = process.env.LOG_LEVEL;
}

//检查环境变量
function checkEnv() {
  const dotenvPath = path.resolve(userHome, ".env");
  const dotenv = require("dotenv");
  if (pathExists(dotenvPath)) {
    dotenv.config({
      path: dotenvPath,
    });
  }
  // 没有配置环境变量则创建一个
  createDefaultConfig();
  console.log("脚手架默认环境变量", process.env.CLI_HOME_PATH);
}

// 脚手架默认环境变量设置
function createDefaultConfig() {
  const cliConfig = {
    home: userHome,
  };
  if (process.env.CLI_HOME) {
    cliConfig["cliHome"] = path.join(userHome, process.env.CLI_HOME);
  } else {
    cliConfig["cliHome"] = path.join(userHome, constant.DEFAULT_CLI_HOME);
  }
  process.env.CLI_HOME_PATH = cliConfig.cliHome;
}

// npm全局更新检查
async function checkGlobalUpdate() {
  // 1. 获取当前版本和名字
  const currentVersion = pkg.version;
  const npmName = pkg.name;
  // 2. 从npm api中获取脚手架信息
  const { getNpmSemverVersion } = require("@luo-cli-dev/get-npm-info");
  // 3. 拿到脚手架最新版本
  const lastVersion = await getNpmSemverVersion(currentVersion, npmName);
  // log.info('最新脚手架版本为：',lastVersion,currentVersion,npmName)
  // 4. 比较版本并提示
  if (lastVersion && semver.gt(lastVersion, currentVersion)) {
    log.warn(
      colors.yellow(`请手动更新 ${npmName}，当前版本：${currentVersion}，最新版本：${lastVersion}
                更新命令： npm install -g ${npmName}`)
    );
  }
}
